Skip to content

Auto-generate rbs_ast_ruby_annotations_t union from config.yml#2939

Open
ksss wants to merge 2 commits intoruby:masterfrom
ksss:auto-generate-ruby-annotations-union
Open

Auto-generate rbs_ast_ruby_annotations_t union from config.yml#2939
ksss wants to merge 2 commits intoruby:masterfrom
ksss:auto-generate-ruby-annotations-union

Conversation

@ksss
Copy link
Copy Markdown
Collaborator

@ksss ksss commented Apr 24, 2026

Summary

  • The rbs_ast_ruby_annotations_t union in include/rbs/ast.h was hand-written with only 6 members, while ast.h defines 14 rbs_ast_ruby_annotations_*_t structs and src/parser.c casts all 14 to rbs_ast_ruby_annotations_t *. The code worked only because downstream consumers (e.g. ext/rbs_extension/ast_translation.c) just read .base and re-cast to the concrete struct — the union value itself is never instantiated.
  • Teach templates/template.rb to collect nodes under RBS::AST::Ruby::Annotations::* and render the union body from them in templates/include/rbs/ast.h.erb, so future annotation additions stay in sync automatically.
  • As a side benefit, replace the 13 hand-maintained allowlist_type entries in rust/ruby-rbs-sys/build.rs with a single regex rbs_ast_ruby_annotations_.*, so bindgen picks up every annotation struct (and the union itself) regardless of whether we build against the pinned vendor or the current master. This also silently closes the missing-entry for rbs_ast_ruby_annotations_module_self_annotation_t.

Why the Rust drift went unnoticed

rust/ruby-rbs-sys/build.rs was last updated on 2026-03-12; RBS::AST::Ruby::Annotations::ModuleSelfAnnotation was added to config.yml on 2026-04-06. The Rust CI workflow pins rbs_version = v4.0.2 and vendors that tag via rake rust:rbs:sync, so the CI build consumes a config.yml that predates the new annotation. cargo build therefore only failed for developers who use rake rust:rbs:symlink to work against the current master. After this PR, the regex-based allowlist stays in sync with config.yml on both sides (pinned vendor and master), so adding a new annotation only requires editing config.yml.

Test plan

  • bundle exec rake compile (clean, no warnings)
  • bundle exec rake test — 936 tests / 0 failures
  • cargo clean && cargo test under rake rust:rbs:sync (CI-equivalent setup, pinned v4.0.2 vendor)
  • cargo clean && cargo test under rake rust:rbs:symlink (master HEAD vendor — previously failed with cannot find type 'rbs_ast_ruby_annotations_module_self_annotation_t')
  • cargo clippy — no warnings in both modes
  • Generated include/rbs/ast.h matches template output after clang-format (equivalent to rake confirm_templates)

🤖 Generated with Claude Code

The union `rbs_ast_ruby_annotations_t` was previously maintained by
hand in ast.h.erb with only 6 members, while 14 annotation structs
existed and were all cast to this union pointer in parser.c. This
drift went unnoticed because downstream code only touches `.base`
and never instantiates the union as a value.

Generate the union members from the annotation entries in config.yml
so future additions stay in sync automatically.

As a side benefit, ruby-rbs-sys/build.rs can now allowlist the union
type alone and rely on bindgen's transitive allowlisting to pull in
every `rbs_ast_ruby_annotations_*_t` member, replacing the
hand-maintained list of 13 individual allowlist entries (which had
itself drifted by missing module_self_annotation_t).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ksss ksss added this to the RBS 4.1 milestone Apr 24, 2026
The previous `allowlist_type("rbs_ast_ruby_annotations_t")` relied on
bindgen's transitive allowlisting through the union. That works against
the current master (where the union lists all 14 annotation members
after auto-generation), but CI vendors the pinned v4.0.2 tag via
`rake rust:rbs:sync`, whose union only has 6 members. The other 7
annotation structs referenced by ruby-rbs therefore never appeared in
bindings.rs, breaking `cargo test`.

Switch to the regex `rbs_ast_ruby_annotations_.*` which matches every
annotation struct directly (and still includes the union itself) in
both the pinned vendor and the current master, preserving the
auto-follow property intended by this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant